Skip to content

go2tool: add Go2 wifi setup workflow#2421

Open
kezaer wants to merge 4 commits into
dimensionalOS:mainfrom
kezaer:codex/go2-wifi-setup
Open

go2tool: add Go2 wifi setup workflow#2421
kezaer wants to merge 4 commits into
dimensionalOS:mainfrom
kezaer:codex/go2-wifi-setup

Conversation

@kezaer

@kezaer kezaer commented Jun 8, 2026

Copy link
Copy Markdown

TL;DR:

solves two concerns:

This PR turns Go2 Wi-Fi setup from a multiple commands into one command: configure Wi-Fi, find the robot’s new IP, and verify it.

On macOS, Bluetooth permission is tied to the app that launched the code. Depending on how you run go2tool, macOS may think Bluetooth access belongs to Terminal, iTerm, Python, uv, or another wrapper process. On some setups BLE scan/provision can fail, hang, or even crash before the robot is found.
This PR adds a Mac BLE helper, which wraps the same Python/Bleak code in a small macOS .app. That app has the proper Bluetooth permission strings in its Info.plist, so macOS TCC has a stable app identity to authorize.

Problem

This PR was born from my issues of setting up a Go2 dog on a local Wifi network.
I powered up the dog and told Codex to connect it to the local Wifi.

It took codex 1 hour end-to-end because of multiple steps necessary + the peculiarities of bluetooth permissions on macOS depending on the terminal used.

The workflow before this PR: provision over BLE, wait for the robot to join the network, rediscover it on LAN, pick the right IP, and then run DimOS with that IP.

dimos go2tool discover 
dimos go2tool connect-wifi --ssid ‹wifi> 
dimos go2tool discover (wait for the IP to become discoverable)
dimos --robot-ip ‹robot-ip> run unitree-go2

Now the flow becomes:

dimos go2tool setup --ssid ‹wifi› 
dimos --robot-ip ‹printed-ip> run unitree-go2

If multiple dogs are visible, use:

dimos go2tool setup --ssid ‹wifi› --serial ‹serial>

macOS Bluetooth permissions peculiarity

On macOS, Bluetooth access is controlled by TCC permissions. Running Bleak directly from a terminal means Bluetooth authorization may be attached to Terminal, iTerm, Python, uv, or some other launch context. On some Macs this works. On others, scan/provision can fail or behave inconsistently even though the robot and code are fine.

This PR adds a macOS helper .app path so Bluetooth access goes through a normal LaunchServices app bundle with Bluetooth usage keys. That gives macOS a clearer thing to authorize.

Instead of Bluetooth access coming from “Terminal running Python,” macOS sees “DimOS BLE Helper.app wants Bluetooth.” That app has the proper Bluetooth permission strings in its Info.plist, so macOS TCC has a stable app identity to authorize.

Flow:

go2tool -> launch helper .app -> helper runs BLE scan/provision -> returns result to go2tool

This only changes how macOS sees and authorizes the process using Bluetooth, not the Go2 BLE protocol.

It also fixes operational flakiness:

  • The robot may take a few seconds to appear on LAN after Wi-Fi provisioning, so setup retries rediscovery.
  • If multiple Go2s are visible, "setup' retries rediscovery. can select by '--serial', '--name' •or '--mac' instead of guessing.
  • 'setup' verifies the discovered IP with the Go2 '/con_notify endpoint before printing it.
  • '--password' is still supported, but the interactive path uses a hidden prompt, and helper output redacts the password.

Solution

  • Add dimos go2tool setup and verify for BLE provisioning, LAN rediscovery, and no-movement endpoint verification.
  • Add BLE backend selection so macOS can use a LaunchServices helper while Linux/direct users keep the existing Bleak path.
  • Keep wifi passwords out of argv in normal use and out of helper request/progress output, with consistent [REDACTED] redaction.
  • Verify Go2 LAN reachability with POST /con_notify, allow_redirects=False, and expected payload validation.
  • Add focused Go2 CLI tests plus targeted docs/runbook updates without reformatting unrelated docs.

How to Test

  • uv run pytest dimos/robot/unitree/go2/cli -q -> 34 passed, with existing pytest-asyncio deprecation warnings and a subprocess ResourceWarning.
  • uv run ruff check dimos/robot/unitree/go2/cli/go2tool.py dimos/robot/unitree/go2/cli/macos_ble_helper.py dimos/robot/unitree/go2/cli/setup.py dimos/robot/unitree/go2/cli/verify.py dimos/robot/unitree/go2/cli/test_macos_ble_helper.py -> passed.
  • uv run ruff format --check dimos/robot/unitree/go2/cli/go2tool.py dimos/robot/unitree/go2/cli/macos_ble_helper.py dimos/robot/unitree/go2/cli/setup.py dimos/robot/unitree/go2/cli/verify.py dimos/robot/unitree/go2/cli/test_macos_ble_helper.py -> passed.
  • uv run mypy dimos/robot/unitree/go2/cli/go2tool.py dimos/robot/unitree/go2/cli/macos_ble_helper.py dimos/robot/unitree/go2/cli/setup.py dimos/robot/unitree/go2/cli/verify.py -> passed.
  • uv run doclinks --dry-run docs/coding-agents/go2-wifi-provisioning.md docs/coding-agents/index.md docs/platforms/quadruped/go2/index.md docs/usage/cli.md -> passed.
  • uv run dimos go2tool --help, uv run dimos go2tool connect-wifi --help, uv run dimos go2tool setup --help, and uv run dimos go2tool verify --help -> passed.

Full uv run pytest was not rerun locally because the default suite pulls authenticated LFS data from https://lfs.dimensionalos.com.

@greptile-apps

greptile-apps Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR collapses the multi-step Go2 Wi-Fi provisioning flow into a single dimos go2tool setup command that covers BLE provisioning, LAN rediscovery, and a no-movement HTTP endpoint verification. It also adds a macOS LaunchServices helper app that routes Bluetooth traffic through an app bundle to side-step TCC permission ambiguity.

  • New commands: setup (full provisioning workflow) and verify (standalone /con_notify probe); password is prompted with hide_input=True and consistently redacted via [REDACTED] throughout progress, error, and summary output.
  • Pluggable BLE backend (auto/helper/direct): on macOS auto uses the LaunchServices helper for finite scans; timeout=0 falls back to direct Bleak streaming.
  • macos_ble_helper: builds/caches a .app bundle with required NSBluetooth*UsageDescription keys, passes credentials via a 0o600 temp file (never in argv), and reads structured JSON progress/response files.

Confidence Score: 4/5

Safe to merge after addressing the subprocess hang risk in the macOS helper path.

The subprocess.run call in _invoke_helper has no timeout parameter. Because open -W waits indefinitely for the helper app to exit, any scenario where the helper process becomes unresponsive — a macOS TCC dialog the user has not dismissed, the Bluetooth stack stalling before the BLE scan timeout fires, or a crash during app initialization — will block the calling thread permanently. The thread runs in a ThreadPoolExecutor via run_in_executor, so asyncio task cancellation cannot interrupt it. The rest of the change is well-structured: the orchestration layer is cleanly separated from I/O, redaction is consistent across all output paths, and the test suite covers the important edge cases.

dimos/robot/unitree/go2/cli/macos_ble_helper.py — specifically the subprocess.run call in _invoke_helper around line 341.

Important Files Changed

Filename Overview
dimos/robot/unitree/go2/cli/macos_ble_helper.py New macOS LaunchServices BLE wrapper; subprocess.run in _invoke_helper has no timeout, risking an indefinite hang if the helper process becomes unresponsive.
dimos/robot/unitree/go2/cli/go2tool.py Adds setup and verify commands, pluggable BLE backend selection (auto/helper/direct), and consistent password redaction across all commands.
dimos/robot/unitree/go2/cli/setup.py New orchestration layer for BLE provisioning to LAN rediscovery to verification, with injected callables for testability and consistent password redaction throughout.
dimos/robot/unitree/go2/cli/verify.py New no-movement probe against /con_notify; correctly restricts success to 2xx only and validates the base64-encoded payload structure.
dimos/robot/unitree/go2/cli/test_go2tool.py Comprehensive tests covering backend routing, redaction, retry logic, verify exit codes, and the full setup path.
dimos/robot/unitree/go2/cli/test_setup.py Unit tests for setup_go2_wifi orchestration covering success, verification failure, ambiguous robot selection, and password redaction.
dimos/robot/unitree/go2/cli/test_macos_ble_helper.py Tests for helper app validation, subprocess invocation, thread offloading, and password redaction from request/progress/argv.
dimos/robot/unitree/go2/cli/test_verify.py Tests for the verification probe.

Sequence Diagram

sequenceDiagram
    participant User
    participant go2tool as go2tool setup
    participant BLE as BLE Backend
    participant Helper as macOS Helper .app
    participant LAN as LAN Discovery
    participant Robot as Go2 Robot

    User->>go2tool: dimos go2tool setup --ssid X
    go2tool->>go2tool: prompt password (hidden)
    alt macOS auto/helper backend
        go2tool->>Helper: open -W -n (request.json via tmpfile)
        Helper->>Robot: BLE scan + provision_wifi
        Robot-->>Helper: serial
        Helper-->>go2tool: response.json (serial)
    else Linux/direct backend
        go2tool->>BLE: find_robots(timeout)
        BLE-->>go2tool: device list
        go2tool->>BLE: provision_wifi(address, ssid, password)
        BLE->>Robot: BLE credentials
        Robot-->>BLE: serial
        BLE-->>go2tool: serial
    end
    loop up to rediscovery_attempts
        go2tool->>LAN: discover() via run_in_executor
        LAN-->>go2tool: Go2Device list
        go2tool->>go2tool: match by serial
    end
    go2tool->>Robot: "POST /con_notify (allow_redirects=False)"
    Robot-->>go2tool: 200 + base64 payload
    go2tool-->>User: "result=ok robot_ip=X.X.X.X"
Loading

Reviews (4): Last reviewed commit: "docs: clarify Go2 wifi setup options" | Re-trigger Greptile

Comment thread dimos/robot/unitree/go2/cli/verify.py Outdated
@kezaer kezaer changed the title [codex] add go2 wifi setup workflow Add Go2 Wi-Fi setup workflow Jun 8, 2026
@kezaer kezaer changed the title Add Go2 Wi-Fi setup workflow go2tool: add Go2 wifi setup workflow Jun 8, 2026
@greptile-apps

greptile-apps Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Want your agent to iterate on Greptile's feedback? Try greploops.

leshy

This comment was marked as duplicate.

@leshy leshy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually this Jetson and Eric can use current go2tool already on Mac, what's the issue this is solving?

pls don't use AI generated PR description, describe in your own words

@kezaer

kezaer commented Jun 9, 2026

Copy link
Copy Markdown
Author

actually this Jetson and Eric can use current go2tool already on Mac, what's the issue this is solving?

pls don't use AI generated PR description, describe in your own words

Manually composed a thorough PR description.
Also updated the docs for more clarity on params.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants